<?php
/**
 * User: Titan
 * Date: Sep 28, 2010
 * Time: 6:48:11 PM
 */

$load = 'install';

define('CONFIGURATION_MODE', 'INSTALL');
define('ROOT', dirname(__FILE__));

require_once('./includes/common.inc');
require_once('./libraries/Object.php');
require_once('./libraries/Loader.php');
require_once('./libraries/Controller.php');
require_once('./includes/install.inc');

class Install extends Controller 
{
	var $content = array();
	
	public function __construct() 
	{
		
	}
	
	/**
	 * run()
	 * 
	 * Enter description here ...
	 * 
	 */
	public static function run() 
	{
		require_once('./libraries/Initializer.php');
		Initializer::initialize(INITIALIZE_CONFIGURATION);
		
		require_once('./modules/system/system.install');
		require_once(ROOT . '/libraries/Athena.php');
		
		page_header();
		
		include_once('./libraries/Moduler.php');
		
		$module_list['system']['filename'] = 'modules/system/system.module';
//		$module_list['filter']['filename'] = 'modules/filter/filter.module';
		Loader::import('module', 'system');
//		Loader::import('module', 'filter');
		Moduler::moduleList(TRUE, FALSE, $module_list);
		
		maintenance_theme();
		
		$verify = Install::verifySettings();
		
		if ($verify) 
		{
			require_once('./libraries/Storage.php');
			require_once('./libraries/Db.php');
			Db::init();
			
			$task = Install::verifyAthena();
			if ($task == 'done') 
			{
				Install::alreadyInstalled();
			}
		}
		else 
		{
			require_once('./libraries/Storage-Install.php');
			$task = NULL;
		}
		
		/*
		if (empty($_GET['profile'])) 
		{
			if ($profile = Install::selectProfile()) 
			{
				
			}
		}
		*/
		
		if (!$task) 
		{
			$db_url = Config::dbUrl();
			if (!$verify && (!empty($db_url) || $db_url != 'mysql://username:password@localhost/databasename')) 
			{
				Install::alreadyInstalled();
			}
			
			Install::checkRequirements($verify);
			
			$messages = Athena::getMessages();
			if (!empty($messages['error'])) 
			{
				Install::taskList('requirements');
				page_title('Requirements Problem');
				print(render('install_page', ''));
				exit;
			}
			
			if (!$verify) 
			{
				Install::changeSettings();
			}
			
			install_system();
		}
		else 
		{
			
		}
	}
	
	/**
	 * tasks()
	 * 
	 * Enter description here ...
	 * 
	 * @param string $task
	 */
	public static function tasks($task) 
	{
		$messages = isset($_SESSION['messages']) ? $_SESSION['messages'] : '';
		Initializer::initialize(INITIALIZE_FULL);
		
		$_SESSION['messages'] = $messages;
		
		$url = Config::baseUrl() . '/install.php?profile=default';
		
		if (empty($task)) 
		{
			Storage::set('install_task', 'profile-install');
			$task = 'profile-install';
		}
		
		if ($task == 'profile-install') 
		{
			$modules = Install::profileModules();
			$files = Moduler::rebuildCache();
			
			$operations = array();
			foreach ($modules as $module) 
			{
				$operations[] = array(array('Install', 'installModuleBatch'), array($module, $files[$module]->info['name']));
			}
			
			$batch = array(
				'operations' => $operations,
				'finished' => array('Install', 'installProfileBatchFinished'),
				'title' => 'Installing Athena',
				'error_message' => 'The installation has encountered an error.'
			);
			
			Storage::set('install_task', 'profile-install-batch');
		}
		
		if ($task == 'profile-install-batch') 
		{
			Loader::import('Batch');
			$output = Batch::page();
		}
		
		if (!in_array($task, Install::reservedTasks())) 
		{
			$task = 'profile-finished';
		}
		
		if ($task == 'profile-finished') 
		{
			// @TODO: add some locale stuff
			
			$task = 'finished';
		}
		
		if ($task == 'finished') 
		{
			page_title('Athena installation complete');
			$messages = Athena::getMessages();
			$output = '<p>Congratulations, Athena has been successfully installed.</p>';
			$output .= '<p>' . isset($messages['error']) ? 'Please review the messages above before continuing on to <a href="' . url('') . '">your new site</a>.' : 'You may now visit <a href="' . url('') . '">your new site</a>.';
			$task = 'done';
		}
		
		if ($task == 'done') 
		{
			// 1. rebuild menu
			
			// 2. sync actions
			
			// 3. flush css/js
			
			// 4. 
			Storage::set('install_profile', 'default');
		}
		
		Install::taskList($task);
		Storage::set('install_task', $task);
		
		if (isset($output)) 
		{
			print(render('maintenance_page', $output));
		}
	}
	
	/**
	 * profileModules()
	 * 
	 * Enter description here ...
	 * 
	 * @param string $profile
	 * @return array
	 */
	public static function profileModules($profile = 'default') 
	{
		if ($profile == 'default') 
		{
			return array();
		}
	}
	
	/**
	 * reservedTasks()
	 * 
	 * Enter description here ...
	 * 
	 * @return multitype:string 
	 */
	public static function reservedTasks() 
	{
		return array('configure', 'profile-install', 'profile-install-batch', 'locale-initial-import', 'locale-initial-batch', 'profile-finished', 'locale-remaining-batch', 'finished', 'done');
	}

	/**
	 * changeSettings()
	 * 
	 * Enter description here ...
	 * 
	 */
	public static function changeSettings()
	{
		$db_url = Config::dbUrl();
		
		$url = parse_url(is_array($db_url) ? $db_url['default'] : $db_url);
		$db_user = isset($url['user']) ? urldecode($url['user']) : '';
		$db_pass = isset($url['pass']) ? urldecode($url['pass']) : '';
		$db_host = isset($url['host']) ? urldecode($url['host']) : '';
		$db_port = isset($url['port']) ? urldecode($url['port']) : '';
		$db_path = ltrim(urldecode($url['path']), '/');
		$conf_path = './' . Config::confPath(FALSE, TRUE);
		$settings_file = $conf_path . '/settings.php';
		
		// We always need this because we want to run form_get_errors.
		include_once './includes/form.inc';
		Install::taskList('database');
		
//		$output = drupal_get_form('install_settings_form', $profile, $install_locale, $settings_file, $db_url, $db_type, $db_prefix, $db_user, $db_pass, $db_host, $db_port, $db_path);
		$output = Install::settingsForm($settings_file, $db_url, $db_user, $db_pass, $db_host, $db_port, $db_path);
		page_title('Database configuration');
		print render('install_page', $output);
		exit;
	}
	
	public static function settingsForm($settings_file, $db_url, $db_user, $db_pass, $db_host, $db_port, $db_path) 
	{
		if (empty($db_host)) 
		{
			$db_host = 'localhost';
		}
		
		$form['basic_options'] = array(
			'#type' => 'fieldset', 
			'#title' => 'Basic options', 
			'#description' => '<p>To set up your @drupal database, enter the following information.</p>'
		);
		
		$form['basic_options']['db_path'] = array(
			'#type' => 'textfield', 
			'#title' => 'Database name', 
			'#value' => $db_path, 
			'#size' => 45, 
			'#required' => TRUE
		);
		
		// Database username
		$form['basic_options']['db_user'] = array(
			'#type' => 'textfield', 
			'#title' => 'Database username', 
			'#value' => $db_user, 
			'#size' => 45, 
			'#required' => TRUE
		);
		
		// Database username
		$form['basic_options']['db_pass'] = array(
			'#type' => 'password', 
			'#title' => 'Database password', 
			'#value' => $db_pass, 
			'#size' => 45
		);
		
		$form['advanced_options'] = array(
			'#type' => 'fieldset', 
			'#title' => 'Advanced options', 
			'#collapsible' => TRUE, 
			'#collapsed' => TRUE, 
			'#description' => "These options are only necessary for some sites. If you're not sure what you should enter here, leave the default settings or check with your hosting provider."
		);
		
		// Database host
		$form['advanced_options']['db_host'] = array(
			'#type' => 'textfield', 
			'#title' => 'Database host', 
			'#value' => $db_host, 
			'#size' => 45, 
			// Hostnames can be 255 characters long.
			'#maxlength' => 255, 
			'#required' => TRUE, 
			'#description' => 'If your database is located on a different server, change this.'
		);
		
		// Database port
		$form['advanced_options']['db_port'] = array(
			'#type' => 'textfield', 
			'#title' => 'Database port', 
			'#value' => $db_port, 
			'#size' => 45, 
			// The maximum port number is 65536, 5 digits.
			'#maxlength' => 5, 
			'#description' => 'If your database server is listening to a non-standard port, enter its number.'
		);
		
		$form['save'] = array(
			'#type' => 'submit', 
			'#value' => 'Save and continue'
		);
		
		$form['errors'] = array();
		$form['settings_file'] = array(
			'#type' => 'value', 
			'#value' => $settings_file
		);
		$form['_db_url'] = array(
			'#type' => 'value'
		);
		$form['#action'] = "install.php";
		$form['#redirect'] = FALSE;
		
		$form = new Form($form, 'install_settings_form');
		$output = $form->build('install_settings_form');
		
		return $output;
	}
	
	/**
	 * checkRequirements()
	 * 
	 * Enter description here ...
	 * 
	 * @param boolean $verify
	 */
	public static function checkRequirements($verify) 
	{
		if (!$verify) 
		{
			$writable = FALSE;
			$conf_path = './' . Config::confPath(FALSE, TRUE);
			$settings_file = $conf_path . '/settings.php';
			$file = $conf_path;
			$exists = FALSE;
			
			if (verify_install_file($conf_path, FILE_EXIST, 'dir')) 
			{
				$file = $settings_file;
				if (verify_install_file($settings_file, FILE_EXIST)) 
				{
					$exists = TRUE;
					$writable = verify_install_file($settings_file, FILE_READABLE|FILE_WRITABLE);
				}
			}
			
			if (!$exists) 
			{
				Athena::setMessage('The Athena installer requires that you create a settings file as part of the installation process.
<ol>
<li>Copy the ' . $file . ' file to ' . $settings_file . '.</li>
<li>Change file permissions so that it is writable by the web server. If you are unsure how to grant file permissions, please consult the <a href="http://drupal.org/server-permissions">on-line handbook</a>.</li>
</ol>
More details about installing Drupal are available in INSTALL.txt.', 'error');
			}
			else if (!$writable) 
			{
				Athena::setMessage('The Athena installer requires write permissions to ' . $file . ' during the installation process. If you are unsure how to grant file permissions, please consult the <a href="http://drupal.org/server-permissions">on-line handbook</a>.', 'error');
			}
		}
		
		// requirements for profiles
		// @TODO: add these
	}
	
	/**
	 * findProfiles()
	 * 
	 * Enter description here ...
	 * 
	 * @return Ambigous <An, multitype:, stdClass>
	 */
	public static function findProfiles() 
	{
		return Athena::scanDirectory('./profiles', '\.profile$', array('.', '..', 'CVS'), 0, TRUE, 'name', 0);
	}
	
	/**
	 * selectProfile()
	 * 
	 * Enter description here ...
	 * 
	 */
	public static function selectProfile() 
	{
		Loader::import('Form');
		
		$profiles = Install::findProfiles();
		if (count($profiles) == 1) 
		{
			$profile = array_pop($profiles);
			require_once($profile->filename);
			return $profile->name;
		}
		else if (count($profiles) > 1) 
		{
			if (!empty($_POST['profile'])) 
			{
				foreach ($profiles as $profile) 
				{
					if ($_POST['profile'] == $profile->name) 
					{
						return $profile->name;
					}
				}
			}
			
			Install::taskList('profile-select');
			page_title('Select an installation profile');
			print(Renderer::render('install_page', Install::configurationForm()));
			
			exit;
		}
	}
	
	public static function taskList($active = NULL) 
	{
		// Default list of tasks.
		$tasks = array(
			'profile-select' => 'Choose profile', 
			'requirements' => 'Verify requirements', 
			'database' => 'Set up database', 
			'profile-install-batch' => 'Install profile', 
			'configure' => 'Configure site'
		);
		
		$profiles = Install::findProfiles();
		$profile = isset($_GET['profile']) && isset($profiles[$_GET['profile']]) ? $_GET['profile'] : '.';
		
		// If we have only one profile, remove 'Choose profile'
		// and rename 'Install profile'.
		if (count($profiles) == 1)
		{
			unset($tasks['profile-select']);
			$tasks['profile-install-batch'] = 'Install site';
		}
		
		// Add tasks defined by the profile.
		if ($profile)
		{
			$function = $profile . '_profile_task_list';
			if (function_exists($function))
			{
				$result = $function();
				if (is_array($result))
				{
					$tasks += $result;
				}
			}
		}
		
		// Add finished step as the last task.
		$tasks += array('finished' => 'Finished');
		
		// Let the theming function know that 'finished' and 'done'
		// include everything, so every step is completed.
		if (in_array($active, array('finished', 'done')))
		{
			$active = NULL;
		}
		
		$this->content['left'] =  render_task_list($tasks, $active);
	}
	
	/**
	 * alreadyInstalled()
	 * 
	 * Enter description here ...
	 * 
	 */
	public static function alreadyInstalled() 
	{
		
		exit;
	}
	
	/**
	 * verifySettings()
	 * 
	 * Enter description here ...
	 * 
	 * @return boolean
	 */
	public static function verifySettings() 
	{
		$db_url = Config::dbUrl();
		
		if (!empty($db_url)) 
		{
			Loader::import('Form');
			
			$url = parse_url(is_array($db_url) ? $db_url['default'] : $db_url);
			
			$db_user = urldecode($url['user']);
			$db_pass = isset($url['pass']) ? urldecode($url['pass']) : NULL;
			$db_host = urldecode($url['host']);
			$db_port = isset($url['port']) ? urldecode($url['port']) : '';
			$db_path = ltrim(urldecode($url['path']), '/');
			$settings_file = './'. Config::confPath(FALSE, TRUE) .'/settings.inc';
			
			$form_state = array();
			
			$errors = Form::error();
			if (empty($errors)) 
			{
				return TRUE;
			}
		}
		
		return FALSE;
	}
	
	/**
	 * verifyAthena()
	 * 
	 * Enter description here ...
	 * 
	 * @return mixed|boolean
	 */
	public static function verifyAthena()
	{
		$result = @Db::query("SELECT value FROM variable WHERE name = '%s'", 'install_task');
		if ($result) 
		{
			return unserialize(Db::result($result));
		}
		else 
		{
			return FALSE;
		}
	}
	
	/**
	 * configurationForm()
	 * 
	 * Enter description here ...
	 * 
	 * @return Form
	 */
	public static function configurationForm() 
	{
		$form = array(
			'#id' => unique_id('install-configuration-form'), 
			'#action' => 'install.php?op=init', 
			'#method' => 'POST', 
			'#children' => array(
				'db_host' => array(
					'#type' => 'textfield', 
					'#title' => 'Database Host', 
					'#size' => 45, 
					'#value' => 'localhost', 
					'#description' => 'Enter the hostname of the server where your database is located.', 
					'#order' => 0
				), 
				'db_path' => array(
					'#type' => 'textfield', 
					'#title' => 'Database Name', 
					'#size' => 45, 
					'#value' => 'bugzapp', 
					'#description' => 'Enter the name of your database. (If you have not previously setup a database, one will be created.)', 
					'#order' => 1
				), 
				'db_user' => array(
					'#type' => 'textfield', 
					'#title' => 'Database Username', 
					'#size' => 45, 
					'#order' => 2
				), 
				'db_pass' => array(
					'#type' => 'password', 
					'#title' => 'Database Password', 
					'#size' => 45, 
					'#order' => 3
				), 
				'db_port' => array(
					'#type' => 'textfield', 
					'#title' => 'Database Port', 
					'#size' => 45, 
					'#value' => 3306, 
					'#description' => 'Only change this if your database server is located on a non-standard port.', 
					'#order' => 4
				), 
				'submit' => array(
					'#type' => 'submit', 
					'#value' => 'Submit', 
					'#order' => 5
				)
			)
		);
		
		$form = new Form($form, 'install_configuration_form');
		
		return $form;
	}
	
	public static function selectProfileForm($profile_files) 
	{
		$profiles = array();
		$names = array();
		
		foreach ($profile_files as $profile)
		{
			include_once($profile->filename);
			
			// Load profile details and store them for later retrieval.
			$function = $profile->name . '_profile_details';
			if (function_exists($function))
			{
				$details = $function();
			}
			
			$profiles[$profile->name] = $details;
			
			// Determine the name of the profile; default to file name if defined name
			// is unspecified.
			$name = isset($details['name']) ? $details['name'] : $profile->name;
			$names[$profile->name] = $name;
		}
		
		$form['#children']['profile'] = array(
			'#type' => 'radioset',
			'#title' => 'Profile',
			'#children' => array()
		);
		
		// Display radio buttons alphabetically by human-readable name. 
		natcasesort($names);
		foreach ($names as $profile => $name)
		{
			$form['#children']['profile']['#children'][$name] = array(
				'#type' => 'radio', 
				'#value' => 'default', 
				'#return_value' => $profile, 
				'#title' => $name, 
				'#description' => isset($profiles[$profile]['description']) ? $profiles[$profile]['description'] : '', 
				'#parents' => array(
					'profile'
				)
			);
		}
		
		$form['#children']['submit'] = array(
			'#type' => 'submit', 
			'#value' => st('Save and continue')
		);
	}
}

/*
 * The main installation function
 */
/*
function install()
{
	if ($_SERVER['REQUEST_METHOD'] == 'POST' && $_POST['form_id'] == 'install_configuration_form')
	{
		$db_url = 'mysql://' . $_POST['db_user'] . ':' . $_POST['db_pass'] . '@' . $_POST['db_host'] . ':' . $_POST['db_port'] . '/' . $_POST['db_path'];
		
		$form_values = array(
			'db_url' => $db_url
		);
		
		install_configuration_form_submit($form_values);
	}
	
	$initializer = new Initializer(INITIALIZE_CONFIGURATION);
	$vars = $initializer->initialize();
	
	include_once ('./includes/form_element.inc');
	include_once ('./includes/form.inc');
	
	athena_add_styles('assets/css/style.css');
	
	include_once ('./includes/module.inc');
	
	$module_list = array(
		'system' => array(
			'file' => 'modules/system/system.module'
		)
	);
	
	include_once ('./includes/file.inc');
	include_once ('./includes/module.inc');
	
	$vars['moduler'] = & get_moduler();
	
	module_list(TRUE, FALSE, $module_list);
	athena_load_file('module', 'system');
	
	$verify = install_verify_settings($vars['config']);
	
	if ($verify)
	{
		require_once ('./includes/database.inc');
		$initializer->initialize_database($vars);
		
		$installed = install_verify($vars['db']);
		if ($installed && $_GET['op'] != 'data')
		{
			// display some sort of confirmation or possibly an error?
			system_page_title('BugZapp Already Installed');
			install_output('<p style="font-weight:bold;">You have already installed BugZapp.</p>');
			
			return $vars;
		}
		
		if (empty($_GET['op']))
		{
			install_launch('install.php?op=config');
		}
		else if ($_GET['op'] == 'data')
		{
			$initializer->initialize_system(&$vars);
			
			install_development_data($vars['db']);
			install_launch('data?op=verifydev');
			
			return $vars;
		}
		
		// install all of the database tables for the system
		$initializer->initialize_system(&$vars);
		$result = install_system($vars['db']);
		
		$initializer->initialize(INITIALIZE_FULL);
		
		if ($result)
		{
			$base_url = $vars['config']->base_url;
			system_page_title('Successful Setup!');
			install_output('<p style="font-weight: bold;">Congratulations! You have setup the BugZapp database. <a href="' . $base_url . '">Click here</a> to go to the BugZapp home page.</p><p><a href="install.php?op=data">Click here</a> to load development data into the database.</p>');
		}
		else
		{
			system_page_title('Setup Failed');
			install_output('<p style="font-weight: bold;">The BugZapp system failed to create its program database.</p>');
		}
	}
	else
	{
		system_page_title('Database Configuration');
		install_output(install_configuration_form());
		
		return $vars;
	}
	
	return $vars;
}
*/

function install_output($data = NULL)
{
	static $output = '';
	
	if (isset($data))
	{
		$output = $data;
	}
	
	return $output;
}

/*
 * Verification of the configured settings
 */
/*
function install_verify_settings(&$config)
{
	if (!empty($config->db_url))
	{
		// TODO: validate db_url
		

		return TRUE;
	}
	else
	{
		require_once ('./includes/cache-install.inc');
	}
	
	return FALSE;
}
*/

/*
 * Check to see if the site has been installed
 * 
 * NOTE: this function probably needs to be better
 */
/*
function install_verify(&$db)
{
	$result = @$db->query('SHOW TABLES');
	if ($result)
	{
		return mysql_num_rows($result) > 0;
	}
}
*/

/*
 * returns the database configuration form
 */
/*
function install_configuration_form()
{
	$form = array(
		
		'#id' => unique_id('install-configuration-form'), 
		'#action' => 'install.php?op=init', 
		'#method' => 'POST', 
		'#inputs' => array(
			'db_host' => array(
				'#type' => 'textfield', 
				'#title' => 'Database Host', 
				'#size' => 45, 
				'#value' => 'localhost', 
				'#description' => 'Enter the hostname of the server where your database is located.', 
				'#order' => 0
			), 
			'db_path' => array(
				'#type' => 'textfield', 
				'#title' => 'Database Name', 
				'#size' => 45, 
				'#value' => 'bugzapp', 
				'#description' => 'Enter the name of your database. (If you have not previously setup a database, one will be created.)', 
				'#order' => 1
			), 
			'db_user' => array(
				'#type' => 'textfield', 
				'#title' => 'Database Username', 
				'#size' => 45, 
				'#order' => 2
			), 
			'db_pass' => array(
				'#type' => 'password', 
				'#title' => 'Database Password', 
				'#size' => 45, 
				'#order' => 3
			), 
			'db_port' => array(
				'#type' => 'textfield', 
				'#title' => 'Database Port', 
				'#size' => 45, 
				'#value' => 3306, 
				'#description' => 'Only change this if your database server is located on a non-standard port.', 
				'#order' => 4
			), 
			'submit' => array(
				'#type' => 'submit', 
				'#value' => 'Submit', 
				'#order' => 5
			)
		)
	);
	
	$output = form_build($form, 'install_configuration_form');
	
	return $output;
}
*/

/*
 * Handles the submission of the database configuration settings form
 */
/*
function install_configuration_form_submit($form_result)
{
	$settings = array(
		'db_url' => $form_result['db_url']
	);
	
	install_write_settings($settings);
}
*/

function install_development_data(&$db)
{
	include_once ('./includes/development/development.inc');
	
	developer_data_create($db);
	feature_data_create($db);
	milestone_data_create($db);
	task_data_create($db);
}

/*
function install_prerender_page(&$vars)
{
	$vars['content'] = install_output();
	$vars['tabs'] = NULL;
	$vars['menu'] = NULL;
}
*/

$install = new Install();
$install->run();
